package com.ruoyi.common.utils.html;


import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.Elements;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 将字符串转换为html
 */
public class HTMLParse {


    public static String removeAllAttributes(String html) {
        // 去除所有HTML标签中的属性，只保留标签名
        return html.replaceAll("<([a-zA-Z][a-zA-Z0-9]*)[^>]*>", "<$1>")
                .replaceAll("<([a-zA-Z][a-zA-Z0-9]*)[^>]*/>", "<$1/>");
    }

    public static String removeStyleAttributes(String html) {
        // 去除所有的style属性
        return html.replaceAll("style\\s*=\\s*\"[^\"]*\"", "")
                .replaceAll("class\\s*=\\s*'[^']*'", "")
                .replaceAll("class\\s*=\\s*\"[^\"]*\"", "")
                .replaceAll("class\\s*=\\s*'[^']*'", "");
    }


    /**
     * 使用正则来处理表格
     *
     * @param htmlContent 带有表格的原文
     * @return 清洗标签后的原文
     */
    public static String removeInlineStylesAndGetTablesByRegex(String htmlContent, Map<String, List<String>> tables) {

        //去除标签上所有属性的原文
        String s = removeAllAttributes(htmlContent);

        // 匹配<table>标签及其所有内容（包括嵌套标签）
        // 匹配连续表格模式：多个表格之间可以有少量非表格内容（如空白符、换行符）
        Pattern pattern = Pattern.compile(
                "(<table[^>]*>[\\s\\S]*?</table>\\s*){2,}",
                Pattern.CASE_INSENSITIVE
        );
        Matcher matcher = pattern.matcher(s);
        int i = 0;
        Map<String, String> strings = new HashMap<>();
        while (matcher.find()) {
            String tableTag = "表格开始table-" + i + "表格结束";
            strings.put(tableTag, matcher.group());
            s = s.replaceAll(matcher.group(), tableTag);
            i++;
        }

        //处理完连续表格后再处理单个表格
        Pattern patternSingle = Pattern.compile("<table[^>]*>[\\s\\S]*?</table>", Pattern.CASE_INSENSITIVE);

        Matcher matcherSingle = patternSingle.matcher(s);
        while (matcherSingle.find()) {
            String tableTag = "表格开始table-" + i + "表格结束";
            strings.put(tableTag, matcherSingle.group());
            s = s.replaceAll(matcherSingle.group(), tableTag);
            i++;
        }

        strings.forEach((k, v) -> {
            Document parse = Jsoup.parse(v);
            Elements allElements = parse.select("table");
            ArrayList<String> strings1 = new ArrayList<>();

            for (Element allElement : allElements) {
                strings1.add(allElement.toString());
            }
            tables.put(k, strings1);

        });
        return s;

    }

    /**
     * 恢复分块中的占位符
     *
     * @param javaList
     * @param list
     * @return
     */
    public static List<String> restoreChunkContent(List<JSONObject> javaList, Map<String, List<String>> list) {
        List<String> tableList = new ArrayList<>();
        for (JSONObject object : javaList) {
            String string = object.getString("content");
            Pattern pattern = Pattern.compile("表格开始(.*?)表格结束");
            Matcher matcher = pattern.matcher(string);

            StringBuilder sb = new StringBuilder();
            String regex = "表格结束";
            string = string + " ";
            String[] split = string.split(regex);
            //当大于1时候才代表有表格
            if (split.length > 1) {
                for (String s : split) {
                    if (!s.contains("表格开始")) {
                        tableList.add(s);
                    }
                }
            }

            while (matcher.find()) {

                String group = matcher.group(1);
                String replace1 = group.replace("表格结束", "");
                List<String> list1 = list.get(replace1);

                for (int i = 0; i < split.length; i++) {
                    if (split.length == 1) {
                        continue;
                    }
                    if (!split[i].contains(group)) {
                        continue;
                    }
                    if (i != split.length) {
                        split[i] += "表格结束";
                    }

                    if (list1 == null) {
                        continue;
                    }
                    String s2 = split[i];
                    int i1 = s2.indexOf("表格开始");
                    if (i1 != -1) {
                        String substring = s2.substring(0, i1);
                        String tableTitle = "";
                        int start = 0;
                        for (String s3 : list1) {
                            if (start > 0) {
                                //将每一个表格拼接前一个表头
                                Document parse = Jsoup.parse(tableTitle);
                                //获取第一个表格的所有tr
                                Element title = parse.select("table").first();
                                //获取第一个表格所有的tr
                                Elements select = title.select("th");
                                Elements getTitle = title.select("tr");

                                //获取第二个表格所有的tr
                                Element body = Jsoup.parse(s3).select("table").first();
                                Elements getBody = body.select("tr");

                                //创建一个表格
                                StringBuilder createTable = new StringBuilder();
                                createTable.append("<table>");
                                for (Element element : select) {

                                    createTable.append(element.outerHtml());
                                }
                                //将第一个表格和第二个表格所有的tr 放入table 中
                                for (Element element : getTitle) {
                                    String html = element.outerHtml();
                                    createTable.append(html);
                                }
                                for (Element element : getBody) {
                                    createTable.append(element.outerHtml());
                                }
                                createTable.append("</table>");
                                String append = substring + createTable.toString();
                                tableList.add(append);
                            } else {
                                //如果是第一个表格那么就直接拼接上下文不用做其他操作
                                start++;
                                String append = substring + s3;
                                tableTitle = append;
                                tableList.add(append);
                            }

                        }
                        String group1 = matcher.group(1);
                        split[i] = split[i].replace(group1, CollectionUtil.join(list1, ""));

                    }
                }
                sb.append(StringUtils.join(split, ""));
            }
            object.put("content2", sb.toString());
        }
        return tableList;
    }

    /**
     * 去除html标签中的style属性，并获取表格
     *
     * @param htmlContent html字符串
     * @param tables      提取的表格存放
     * @return 返回去除style 后的html字符串
     */
    public static String removeInlineStylesAndGetTables(String htmlContent, Map<String, List<String>> tables) {


        //第一步先将文本转换成html 然后将所有的html 标签的style属性去除
        Document parse = Jsoup.parse(htmlContent);
        Elements elements = parse.select("[style]"); // 选择所有包含style属性的元素
        for (Element element : elements) {
            element.removeAttr("style"); // 移除style属性
        }
        Elements body = parse.select("body");
        for (Element element : body) {
            List<Node> nodes = element.childNodes();
            String tag = "";
            int i = 0;
            for (Node child : nodes) {

                if (child instanceof Element) {
                    Element child1 = (Element) child;
                    if ("table".equals(child1.tagName()) && tag.equals(child1.tagName())) {
                        String table = "table-" + i;
                        List<String> list = tables.get(table);
                        list.add(child1.toString());
                        tables.put(table, list);
                        child1.replaceWith(new TextNode(""));
                    } else if ("table".equals(child1.tagName())) {
                        i++;
                        String table = "table-" + i;
                        List<String> objects = new ArrayList<>();
                        Elements select = child1.select("tr");
                        int size = select.size();
                        if (size > 10) {
                            int start = 1;
                            StringBuilder createTable = new StringBuilder();
                            createTable.append("<table>");
                            for (Element element2 : select) {
                                createTable.append(element2.outerHtml());
                                start++;
                                if (start == 10) {
                                    createTable.append("</table><table>");
                                    start = 1;
                                }
                            }
                            createTable.append("</table>");
                            String string = createTable.toString();
                            Document parse1 = Jsoup.parse(string);
                            Elements select1 = parse1.select("table");
                            for (Element element1 : select1) {
                                String string1 = element1.toString();
                                objects.add(string1);
                            }
                        } else {
                            objects.add(child1.toString());
                        }

                        tables.put(table, objects);
                        String tableTag = "表格开始table-" + i + "表格结束";
                        child1.replaceWith(new TextNode(tableTag));
                    }
                    tag = child1.tagName();
                } else if (child instanceof TextNode) {
                    TextNode child1 = (TextNode) child;
                    if (StringUtils.isNotBlank(child1.text())) {
                        tag = child1.text();
                    }
                }
            }
        }
        return parse.text();

    }
}
